package com.coda.clouddisk.service.impl;

import com.coda.clouddisk.context.BaseContext;
import com.coda.clouddisk.entity.*;
import com.coda.clouddisk.exception.BaseException;
import com.coda.clouddisk.mapper.*;
import com.coda.clouddisk.message.MessageContext;
import com.coda.clouddisk.service.SuperService;
import com.coda.clouddisk.service.inter.KeSunAttachmentService;
import com.coda.clouddisk.utils.EntityToMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.UriUtils;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class KeSunAttachmentServiceImpl extends SuperService implements KeSunAttachmentService {
    @Autowired
    private KeSunAttachmentMapper keSunAttachmentMapper;
    @Autowired
    private FiletofolderrecordMapper filetofolderrecord;
    @Autowired
    private FileShareRecordMapper fileShareRecordMapper;
    @Autowired
    private FileShareCordFriendMapper fileShareCordFriendMapper;

    @Override
    public SuperMapper getMapper() {
        return keSunAttachmentMapper;
    }


    /**
     * 文件下载
     *
     * @returnx
     */
    @Override
    public ResponseEntity<Resource> downloadFile(String id) throws MalformedURLException {
        Map<String, Object> map = new HashMap<>();
        map.put("id", id);

        KeSunAttachment fileInfo = (KeSunAttachment) keSunAttachmentMapper.find(map);
        //判断当前文件是否可以下载
        if (fileInfo != null && fileInfo.getCanDownload() == false) {
            throw new BaseException(MessageContext.ERROR_CODE, "当前文件不允许下载");
        }

        if (fileInfo != null) {
            // 获取文件存储路径
            String address = fileInfo.getAddress();
            // 构建文件的完整路径
            Path filePath = Paths.get(address).toAbsolutePath().normalize();
            Resource resource = new UrlResource(filePath.toUri());

            if (resource.exists()) {
                // 设置响应头
                String contentType = "application/octet-stream";
                String encodedFileName = UriUtils.encode(resource.getFilename(), "UTF-8");
                return ResponseEntity.ok()
                        .contentType(MediaType.parseMediaType(contentType))
                        .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + encodedFileName + "\"")
                        .body(resource);
            } else {
                // 文件不存在
                return ResponseEntity.notFound().build();
            }
        } else {
            // 文件信息不存在
            return ResponseEntity.badRequest().build();
        }

    }

    /**
     * 将文件添加进回收站
     * @param data
     * @return
     */
    @Override
    @Transactional
    public KesunReturn toRubbish(Map<String, Object> data) {
        data.put("deleteDate",LocalDateTime.now());
        int result = keSunAttachmentMapper.edit(data);
        KesunReturn kesunReturn = new KesunReturn();
        if (data.get("status") != null && data.get("status").equals("1")){
            if (result != 0) {
                //文件id
                ArrayList<String> ids = (ArrayList<String>) data.get("ids");
                //删除对应的分类中间表
                filetofolderrecord.deletes(ids);

                //创建hashset集合，存放唯一的文件共享id
                HashSet<String> shareIds = new HashSet<>();
                for (String id : ids) {
                    //获取文件共享信息id
                    String shareId = fileShareRecordMapper.getShareIdByIds(id);
                    if (shareId != null){
                        shareIds.add(shareId);
                    }
                }

                //转换为list集合
                ArrayList<String>  shareIdList = new ArrayList<>();
                shareIdList.addAll(shareIds);
                // TODO
                //删除文件共享中间表
                fileShareCordFriendMapper.deletes(shareIdList);
                //删除文件共享记录
                fileShareRecordMapper.deletes(shareIdList);
                kesunReturn.setCode(MessageContext.SUCCESS_CODE);
                kesunReturn.setMsg("删除成功");
            } else {
                kesunReturn.setMsg("删除失败");
                kesunReturn.setCode(MessageContext.ERROR_CODE);
            }
        }else if (data.get("status") != null && data.get("status").equals("0")){
            //恢复文件进入默认文件夹
            ArrayList<String> files = (ArrayList<String>) data.get("ids");
            for (String file : files) {
                Map<String, Object> map = new HashMap<>();
                map.put("category","000000");
                map.put("file",file);
                filetofolderrecord.addToDefault(map);
            }

            kesunReturn.setCode(MessageContext.SUCCESS_CODE);
            kesunReturn.setMsg("恢复成功");
        }
        return kesunReturn;
    }

    /**
     * 按时间分类查找
     *
     * @return
     */
    @Override
    public KesunReturn getFile(Map<String, Object> data) {
        data.put("userId", BaseContext.getCurrentId());
        String date = (String) data.get("date");

        //开始/结束时间
        LocalDateTime start = null;
        LocalDateTime end = null;
        //按年份查找
        if (date.matches("\\d{4}")) {
            int year = Integer.parseInt(date);
            //前一年的结束时间
            start = LocalDateTime.of(year - 1, Month.DECEMBER, 31, 23, 59, 59);
            //后一年的开始时间
            end = LocalDateTime.of(year + 1, Month.JANUARY, 1, 0, 0, 0);

        } else if (date.matches("\\d{4}-\\d{2}")) {   //按月份查找
            //解析为yearMonth对象
            YearMonth yearMonth = YearMonth.parse(date, DateTimeFormatter.ofPattern("yyyy-MM"));
            //前一个月的结束时间
            YearMonth yearMonth1 = yearMonth.minusMonths(1);
            start = yearMonth1.atEndOfMonth().atTime(23, 59, 59);

            //后一个月的开始时间
            YearMonth yearMonth2 = yearMonth.plusMonths(1);
            end = yearMonth2.atDay(1).atStartOfDay();

        } else if (date.matches("\\d{4}-\\d{2}-\\d{2}")) {   //按天查找
            //解析为localdatetime对象
            LocalDate day = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            //前一天的结束时间
            start = day.minusDays(1).atTime(23, 59, 59);
            //后一天的开始时间
            end = day.plusDays(1).atStartOfDay();
        }
        data.put("startDate", start);
        data.put("endDate", end);

        List<KeSunAttachment> files = keSunAttachmentMapper.getFileByTime(data);
        KesunReturn kesunReturn = new KesunReturn();
        if (!(files.isEmpty())) {
            kesunReturn.setCode(MessageContext.SUCCESS_CODE);
            kesunReturn.setObj(files);
        } else {
            kesunReturn.setCode(MessageContext.ERROR_CODE);
            kesunReturn.setMsg("当前日期文件为空");
        }
        return kesunReturn;
    }


    /**
     * 文件上传
     * @param keSunAttachment
     * @param file
     * @return
     */
    @Override
    @Transactional
    public KesunReturn uploadFile(KeSunAttachment keSunAttachment, MultipartFile file) {
        //获取原始文件名
        String filename = file.getOriginalFilename();
        //构造一个唯一的文件名 获取最后一个.的索引
        int index = filename.lastIndexOf(".");
        //得到文件扩展名
        String extname = filename.substring(index);
        //重新设置文件名
        String newFileName = UUID.randomUUID().toString() + extname;
        //文件存放地址
        String address = "D://file//" + newFileName;
        KesunReturn kesunReturn = new KesunReturn();

        try {
            //保存到硬盘（自己电脑）
            file.transferTo(new File(address));
            kesunReturn.setCode(MessageContext.SUCCESS_CODE);
            kesunReturn.setMsg(MessageContext.SUCCESS_MSG);

            String fileId = UUID.randomUUID().toString().substring(0, 8).replace("-", "");
            //保存到数据库
            String newFile = newFileName.substring(0, index);
            keSunAttachment.setId(fileId);
            keSunAttachment.setAddress(address);
            keSunAttachment.setType(extname);
            keSunAttachment.setSize(file.getSize()/1024);
            keSunAttachment.setCanDownload(true);
            keSunAttachment.setCanDownload(true);
            keSunAttachment.setStatus("0");

            User user = new User();
            user.setId(BaseContext.getCurrentId());
            keSunAttachment.setUser(user);
            //对象转集合
            Map<String, Object> map = EntityToMap.convertObjectToMap(keSunAttachment);
            //查询同分类下是否有同名文件
//            keSunAttachmentMapper.isRepetition(map);
            //保存路径到数据库中
            keSunAttachmentMapper.add(map);

            //判断文件是否有分类
            if (map.get("category") == null) {
                map.put("category","000000");
            }
            //将文件添加到该分类下
            for (String category : keSunAttachment.getCategory()) {
                Map<String, Object> fileCategory = new HashMap<>();
                fileCategory.put("file", fileId);
                fileCategory.put("category", category);
                int result = filetofolderrecord.add(fileCategory);  //添加到分类
                if (result == 0) {
                    throw new BaseException(MessageContext.ERROR_CODE, "文件添加分类失败");
                }
            }
        } catch (IOException e) {
            kesunReturn.setCode(MessageContext.ERROR_CODE);
            kesunReturn.setMsg("文件上传失败");
            throw new BaseException(MessageContext.ERROR_CODE, e.getMessage());
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        return kesunReturn;
    }

    /**
     * 修改文件的所属分类
     *
     * @return
     */
    @Override
    public KesunReturn edit() {
        KesunReturn kesunReturn = super.edit();//修改文件
        Map<String, Object> models = super.getModels();

        //判断是否有分类
        if (models.get("category") != null) {
            //修改文件所属分类
            Map<String, Object> map = new HashMap<>();
            map.put("file", models.get("id"));
            ArrayList<String> categoryList = (ArrayList<String>) models.get("category");
            for (String category : categoryList) {
                map.put("category", category);
                filetofolderrecord.add(map);
            }
        }

        return kesunReturn;
    }

}
